//
//   Copyright (c) 2009 Bálint Jánvári
//       www.programmaticmagic.com
//  
//  Permission is hereby granted, free of charge, to any person
//  obtaining a copy of this software and associated documentation
//  files (the "Software"), to deal in the Software without
//  restriction, including without limitation the rights to use,
//  copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the
//  Software is furnished to do so, subject to the following
//  conditions:
//
//  The above copyright notice and this permission notice shall be
//  included in all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
//  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
//  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
//  OTHER DEALINGS IN THE SOFTWARE.

//
//  OMTextDialog.m
//  ObjectiveMagic
//

#import "OMTextDialog.h"
#define IMTextDialogFieldTag 21

@implementation OMTextDialog
@synthesize isVisible;
@synthesize delegate;
@synthesize title;
@synthesize message;
@synthesize password;

- (id)initWithTitle:(NSString*)ttl message:(NSString*)txt password:(BOOL)yesOrNo delegate:(id<OMTextDialogDelegate>)d
{
	self.title = ttl;
	self.message = txt;
	self.delegate = d;
	self.password = yesOrNo;
	return [self init];
}

- (id)initWithTitle:(NSString*)ttl message:(NSString*)txt delegate:(id<OMTextDialogDelegate>)d
{
	return [self initWithTitle:ttl message:txt password:NO delegate:d];
}

- (void)show
{
	if (isVisible) return;
	
	// To make sure that the text field is well-placed, we calculate the size
	// of the message. The additional empty lines make room for the text field.
	currentAlertView = [[UIAlertView alloc] initWithTitle:title message:[message stringByAppendingString:@"\n\n\n"] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];	
	UIFont* font = [(UILabel*)[currentAlertView.subviews objectAtIndex:1] font];
	CGSize s = [[message stringByAppendingString:@"\n\n\n"] sizeWithFont:font constrainedToSize:CGSizeMake(260, 999)];
	// The entire view is translated to appear in the center.
	[currentAlertView setTransform:CGAffineTransformMakeTranslation(0,109)];
	
	UITextField* textField = [[UITextField alloc] initWithFrame:CGRectMake(11,18 + s.height,262,31)];
	textField.borderStyle = UITextBorderStyleBezel;
	textField.secureTextEntry = password;
	textField.backgroundColor = [UIColor whiteColor];
	textField.keyboardAppearance = UIKeyboardAppearanceAlert;
	textField.tag = IMTextDialogFieldTag; // The text field is tagged, and can be located later with ease
	textField.returnKeyType = UIReturnKeyDone;
	textField.delegate = self;
	[currentAlertView addSubview:textField];
	[textField release];
	
	[currentAlertView show];
	// Usually, an alert view is used with autorelease. If this object would be autoreleased before
	// the dialog is dismissed, the alert view would still try to call the delegate methods.
	// To prevent this, we retain ourselves and release later, when the dialog is dismissed
	// This way you can call the dialog like this:
	// [[[[IMTextDialog alloc] initWithTitle:@"Title" message:@"Very long message" delegate:self] autorelease] show];
	[self retain];
	isVisible = YES;
}

- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
	// This makes the return key work just like the OK button
	// on the alert view
	UIAlertView* av = (UIAlertView*)[textField superview];
	[av dismissWithClickedButtonIndex:1 animated:YES];
	return YES;
}

- (void)alertView:(UIAlertView*)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
	// If we do not dismiss the keyboard before hiding the text field, a 
	// debug message will be dropped and the user experiences a short freeze
	[[alertView viewWithTag:IMTextDialogFieldTag] resignFirstResponder];
	switch (buttonIndex)
	{
		case 0:
			if ([delegate respondsToSelector:@selector(textDialogWillCancel:)])
				[delegate textDialogWillCancel:self];
			break;
		case 1:
			if ([delegate respondsToSelector:@selector(textDialog:willFinishWithText:)])
				[delegate textDialog:self willFinishWithText:[(UITextField*)[alertView viewWithTag:IMTextDialogFieldTag] text]];
			break;
	}
}

- (void)didPresentAlertView:(UIAlertView*)alertView
{
	// If the text field becomes first responder before the alert view appears,
	// the entire animation seems to stutter (bug or performance problem?)
	[[alertView viewWithTag:IMTextDialogFieldTag] becomeFirstResponder];
	if ([delegate respondsToSelector:@selector(textDialogDidShow:)]) [delegate textDialogDidShow:self];
}

- (void)willPresentAlertView:(UIAlertView*)alertView
{
	if ([delegate respondsToSelector:@selector(textDialogWillShow:)]) [delegate textDialogWillShow:self];
}

- (void)alertView:(UIAlertView*)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
	switch (buttonIndex)
	{
		case 0:
			if ([delegate respondsToSelector:@selector(textDialogDidCancel:)])
			[delegate textDialogDidCancel:self];
			break;
		case 1:
			if ([delegate respondsToSelector:@selector(textDialog:didFinishWithText:)])
			[delegate textDialog:self didFinishWithText:[(UITextField*)[alertView viewWithTag:IMTextDialogFieldTag] text]];
			break;
	}
	isVisible = NO;
	alertView.delegate = nil;
	[currentAlertView release];
	currentAlertView = nil;
	[self release];
	// The dialog is dismissed, the delegate methods fired, and the object
	// is ready to show another dialog with the same parameters.
}

- (void)dismissWithText:(NSString*)text
{
	// If text is nil, the dialog is cancelled
	// If text is @"", the dialog is NOT cancelled
	if (text == nil)
	{
		[currentAlertView dismissWithClickedButtonIndex:0 animated:YES];
	}
	else
	{
		[(UITextField*)[currentAlertView viewWithTag:IMTextDialogFieldTag] setText:text];
		[currentAlertView dismissWithClickedButtonIndex:1 animated:YES];
	}
}

- (void)dealloc
{
	[message release];
	[title release];
	[super dealloc];
}

@end
